import gym
from gym import error, spaces, utils
from gym.utils import seeding
import pandas
# from  action import *

from object_create import *

##s输出下一个状态

initial_state1 = lp_state.loc[0]
# cpu_state=['cpu0','cpu1','cpu2','cpu3','cpu4','cpu5','cpu6','cpu7','cpu8','cpu9','cpu10','cpu11','cpu12','cpu13','cpu14','cpu15','cpu16','cpu17','cpu18','cpu19','cpu20','cpu21','cpu22','cpu23','cpu24','cpu25','cpu26','cpu27','cpu28','cpu29','cpu30','cpu31','cpu32','cpu33','cpu34','cpu35','cpu36','cpu37','cpu38','cpu39','cpu40','cpu41','cpu42','cpu43','cpu44','cpu45','cpu46','cpu47','cpu48','cpu49','cpu50','cpu51','cpu52','cpu53','cpu54','cpu55','cpu56','cpu57','cpu58','cpu59','cpu60','cpu61','cpu62','cpu63','cpu64','cpu65','cpu66','cpu67','cpu68','cpu69','cpu70','cpu71','cpu72','cpu73','cpu74','cpu75','cpu76','cpu77','cpu78','cpu79','cpu80','cpu81','cpu82','cpu83','cpu84','cpu85','cpu86','cpu87','cpu88','cpu89','cpu90','cpu91','cpu92','cpu93','cpu94','cpu95','cpu96','cpu97','cpu98','cpu99']
# mem_state=['mem0','mem1','mem2','mem3','mem4','mem5','mem6','mem7','mem8','mem9','mem10','mem11','mem12','mem13','mem14','mem15','mem16','mem17','mem18','mem19','mem20','mem21','mem22','mem23','mem24','mem25','mem26','mem27','mem28','mem29','mem30','mem31','mem32','mem33','mem34','mem35','mem36','mem37','mem38','mem39','mem40','mem41','mem42','mem43','mem44','mem45','mem46','mem47','mem48','mem49','mem50','mem51','mem52','mem53','mem54','mem55','mem56','mem57','mem58','mem59','mem60','mem61','mem62','mem63','mem64','mem65','mem66','mem67','mem68','mem69','mem70','mem71','mem72','mem73','mem74','mem75','mem76','mem77','mem78','mem79','mem80','mem81','mem82','mem83','mem84','mem85','mem86','mem87','mem88','mem89','mem90','mem91','mem92','mem93','mem94','mem95','mem96','mem97','mem98','mem99']
import numpy as np


class LoadEnv(gym.Env):
    def __init__(self):
        node = ['vm0', 'vm1', 'vm2', 'vm3', 'vm4', 'vm5', 'vm6', 'vm7', 'vm8', 'vm9']
        self.params = 0
        self.node = ['vm0', 'vm1', 'vm2', 'vm3', 'vm4', 'vm5', 'vm6', 'vm7', 'vm8', 'vm9']
        self.node_num = len(self.node)
        self.memory_percent = self.node.memory_percent  # 每个vm上的内存占用
        self.cpu_percent = self.node.cpu_percent  # 每个vm上的cpu占用
        self.lp_number = self.node.lp_number  # 每个vm上的实体数量
        self.min_cpu = 0  # 最小cpu使用量
        self.max_usage = 1  # 最大cpu使用量


        self.min_mem = 0  # 最小内存使用量
        self.max_mem = 100  # 最大内存使用量
        self.min_num = 0  # 每个vm中最小lp数量
        self.max_num = 100  # 每个vm中最大lp数量
        self.lp_location = self.node.order  # 每个vm中lp编号



        low1 = np.zeros((6, 100))

        text1 = np.ones((2, 100))
        text2 = np.ones((1, 100)) * 8
        text3=np.ones((2,100))
        text4 = np.ones((1, 100)) * 100
        high1 = np.append(text1, text2,text3,text4 ,xis=0)
        self.observation_space = spaces.Box(low=low1, high=high1, shape=(6, 100), dtype=np.float32)
        # self.observation_space = spaces.Dict({
        #     # "obj_num": spaces.Box(low=self.min_obj, high=self.max_obj,shape=(len(self.node),1),dtype=np.uint8),
        #     "cpu_usage": spaces.Box(low=self.min_usage, high=self.max_usage,shape=(len(self.node),1))
        # })
        # self.action_space = spaces.MultiDiscrete(
        #    [10,10]
        # )
        self.action_space = spaces.Discrete(100)
        self.seed()

    def seed(self, seed=None):
        self.np_random, seed = seeding.np_random(seed)
        return [seed]

    # def step(self, action):
    def step(self, action):
        state = self.state



        vm_num_index = np.argsort(np.negative(state[5]))  ######对虚拟机的lp数量进行降序，并求出降序后的索引
        lp_cpu_index = np.argsort(np.negative(state[0]))  ######对lp的cpu进行降序，并求出降序后的索引
        max_vm = vm_num_index[0]  ######最大lp数量的虚拟机的编号
        min_vm = vm_num_index[8]  ######最小lp数量的虚拟机的编号
        # print(vm_num_index)
        # for action in range(10):
        # list=np.where(lp_location == max_vm)
        # list1 = [lp_cpu[i] for i in np.array(list)]
        # print(list.shape)
        index1 = np.where(state[2] == max_vm)  ##最大cpu节点上的lp编号
        index2 = index1[0]  ##最大cpu节点上的lp编号

        lp_cpu1 = state[5][index2]  ##最大cpu节点上的lp的cpu
        # print(np.sum(lp_cpu1))

        lp_cpu_index1 = np.argsort(np.negative(lp_cpu1))  ######最大cpu节点上的lp的cpu降序索引
        # print(index2[lp_cpu_index1])
        index3 = index2[lp_cpu_index1]
        state=self.state

        if len(index3) > action:
            vm_cpu_max = state[3][max_vm]
            vm_cpu_min = state[3][min_vm]
            lp_location1 = state[2]
            vm_cpu1=state[3]
            vm_num1=state[5]
            # print(lp_cpu[index3[0:action+1]])####前action个lp的cpu
            # print(np.sum(lp_cpu[index3[0:action+1]]))####前action个lp的cpu之和
            vm_cpu_max -= np.sum(state[0][index3[0:action + 1]])  ###
            vm_cpu_min += np.sum(state[0][index3[0:action + 1]])
            vm_cpu1[max_vm]=vm_cpu_max
            vm_cpu1[min_vm]=vm_cpu_min
            vm_num1[max_vm]-=action
            vm_num1[min_vm] += action
            # print("max: ",vm_cpu_max)
            # print("min: " ,vm_cpu_min)
            lp_location1[index3[0:action + 1]] = min_vm  ####将前action个lp的位置改为最小的虚拟机
            state = state[0], state[1], lp_location1,vm_cpu1,state[4],vm_num1
            reward = -(np.max(state[0])/np.average(state[0]))
        done = False
        return self.state, reward, done, {}  # 返回状态、奖励、和don


    def reset(self):
        lp_state1=lp_state.loc[self.params]
        vm_state1=vm_state.loc[self.params]
        for i in range(100):
            locals()["cpu" + str(i)] = lp_state1['cpu%s' % i]
            locals()["mem" + str(i)] = lp_state1['mem%s' % i]
            locals()["vm_loc" + str(i)] = lp_state.loc[self.params]['vm_loc%s' % i]
        for i in range(9):
            locals()["cpu_percent" + str(i)] = vm_state1['cpu_percent%s' % i]
            locals()["mem_percent" + str(i)] = vm_state1['mem_percent%s' % i]
            locals()["lp_number" + str(i)] = vm_state1['lp_number%s' % i]
        vm_cpu = np.array([cpu_percent0, cpu_percent1, cpu_percent2, cpu_percent3, cpu_percent4, cpu_percent5,
                           cpu_percent6, cpu_percent7, cpu_percent8])
        vm_mem = np.array([mem_percent0, mem_percent1, mem_percent2,
                           mem_percent3, mem_percent4, mem_percent5, mem_percent6, mem_percent7, mem_percent8])
        vm_num = np.array([lp_number0, lp_number1, lp_number2, lp_number3, lp_number4, lp_number5, lp_number6,
                           lp_number7, lp_number8])
        lp_location = np.array(
            [vm_loc0, vm_loc1, vm_loc2, vm_loc3, vm_loc4, vm_loc5, vm_loc6, vm_loc7, vm_loc8, vm_loc9,
             vm_loc10, vm_loc11, vm_loc12, vm_loc13, vm_loc14, vm_loc15, vm_loc16, vm_loc17, vm_loc18,
             vm_loc19, vm_loc20, vm_loc21, vm_loc22, vm_loc23, vm_loc24, vm_loc25, vm_loc26, vm_loc27,
             vm_loc28, vm_loc29, vm_loc30, vm_loc31, vm_loc32, vm_loc33, vm_loc34, vm_loc35, vm_loc36,
             vm_loc37, vm_loc38, vm_loc39, vm_loc40, vm_loc41, vm_loc42, vm_loc43, vm_loc44, vm_loc45,
             vm_loc46, vm_loc47, vm_loc48, vm_loc49, vm_loc50, vm_loc51, vm_loc52, vm_loc53, vm_loc54,
             vm_loc55, vm_loc56, vm_loc57, vm_loc58, vm_loc59, vm_loc60, vm_loc61, vm_loc62, vm_loc63,
             vm_loc64, vm_loc65, vm_loc66, vm_loc67, vm_loc68, vm_loc69, vm_loc70, vm_loc71, vm_loc72,
             vm_loc73, vm_loc74, vm_loc75, vm_loc76, vm_loc77, vm_loc78, vm_loc79, vm_loc80, vm_loc81,
             vm_loc82, vm_loc83, vm_loc84, vm_loc85, vm_loc86, vm_loc87, vm_loc88, vm_loc89, vm_loc90,
             vm_loc91, vm_loc92, vm_loc93, vm_loc94, vm_loc95, vm_loc96, vm_loc97, vm_loc98, vm_loc99])
        lp_cpu = np.array(
            [cpu0, cpu1, cpu2, cpu3, cpu4, cpu5, cpu6, cpu7, cpu8, cpu9, cpu10, cpu11, cpu12, cpu13, cpu14, cpu15,
             cpu16, cpu17, cpu18, cpu19, cpu20, cpu21, cpu22, cpu23, cpu24, cpu25, cpu26, cpu27, cpu28, cpu29,
             cpu30, cpu31, cpu32, cpu33, cpu34, cpu35, cpu36, cpu37, cpu38, cpu39, cpu40, cpu41, cpu42, cpu43,
             cpu44, cpu45, cpu46, cpu47, cpu48, cpu49, cpu50, cpu51, cpu52, cpu53, cpu54, cpu55, cpu56, cpu57,
             cpu58, cpu59, cpu60, cpu61, cpu62, cpu63, cpu64, cpu65, cpu66, cpu67, cpu68, cpu69, cpu70, cpu71,
             cpu72, cpu73, cpu74, cpu75, cpu76, cpu77, cpu78, cpu79, cpu80, cpu81, cpu82, cpu83, cpu84, cpu85,
             cpu86, cpu87, cpu88, cpu89, cpu90, cpu91, cpu92, cpu93, cpu94, cpu95, cpu96, cpu97, cpu98, cpu99])
        lp_mem = np.array(
            [mem0, mem1, mem2, mem3, mem4, mem5, mem6, mem7, mem8, mem9, mem10, mem11, mem12, mem13, mem14, mem15,
             mem16, mem17, mem18, mem19, mem20, mem21, mem22, mem23, mem24, mem25, mem26, mem27, mem28, mem29,
             mem30, mem31, mem32, mem33, mem34, mem35, mem36, mem37, mem38, mem39, mem40, mem41, mem42, mem43,
             mem44, mem45, mem46, mem47, mem48, mem49, mem50, mem51, mem52, mem53, mem54, mem55, mem56, mem57,
             mem58, mem59, mem60, mem61, mem62, mem63, mem64, mem65, mem66, mem67, mem68, mem69, mem70, mem71,
             mem72, mem73, mem74, mem75, mem76, mem77, mem78, mem79, mem80, mem81, mem82, mem83, mem84, mem85,
             mem86, mem87, mem88, mem89, mem90, mem91, mem92, mem93, mem94, mem95, mem96, mem97, mem98, mem99])
        # self.state1=np.hstack((lp_cpu,lp_mem,lp_location))###初始化状态为lp
        self.state=lp_cpu,lp_mem,lp_location,vm_cpu,vm_mem,vm_num##初始化状态为lp+vm

        return self.state
    def render(self, mode='human', close=False):
        """
        It may be called periodically to print a rendition of the environment. This could
        be as simple as a print statement, or as complicated as rendering a 3D
        environment using openGL. For this example, we will stick with print statements.
        """
        # Render the environment to the screen
        print(f'Step: {self.state}')
        print(f'Balance: {self.step()}')
        # print(f'Shares held: {self.shares_held} (Total sold: {self.total_shares_sold})')
        # print(f'Avg cost for held shares: {self.cost_basis} (Total sales value: {self.total_sales_value})')
        # print(f'Net worth: {self.net_worth} (Max net worth: {self.max_net_worth})')


